package com.quick.db.utils;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Date;
import com.quick.db.L;
import com.quick.db.annotation.Column;
import com.quick.db.annotation.Table;
import com.quick.db.info.ColumnInfo;

import android.content.ContentValues;
import android.database.Cursor;

public class TableUtils {
	public static final String TAG = TableUtils.class.getSimpleName();

	/** 创建数据库-表 */
	public static String createTable(Class<?> clazz) {
		String tableName = getTableName(clazz);
		StringBuilder sb = new StringBuilder(); 
		sb.append("create table " + tableName + "( ");
		Field[] fields = clazz.getDeclaredFields();
		if (!CheckUtils.isArrayEmpty(fields)) {
			for (Field field : fields) {
				field.setAccessible(true);
				Column column = field.getAnnotation(Column.class);
				if (column != null) {
					String columnName = column.value();
					String type = getFiledType(field);
					boolean isPrimaryKey = column.primaryKey();
					if(isPrimaryKey){
						sb.append(columnName + " " + type
								+ " primary key autoincrement,");
					}else{
						sb.append(columnName + " " + type + ",");
					}
				}
			}
		}
		sb = sb.deleteCharAt(sb.length() - 1);
		sb.append(")");
		L.e("建表语句：" + sb.toString());
		return sb.toString();
	}

	/** 获取要创建的表名 */
	public static String getTableName(Class<?> clazz) {
		Table table = clazz.getAnnotation(Table.class);
		String tableName = null;
		if (table != null) {
			tableName = table.value();
		} else {
			tableName = clazz.getSimpleName();
		}
		return tableName;
	}

	/** 获取字段的类别 */
	public static String getFiledType(Field field) {
		Class<?> type = field.getType();
		if (type == int.class || type == Integer.class) {
			return "INTEGER";
		} else if (type == long.class || type == Long.class) {
			return "INTEGER";
		} else if (type == short.class || type == Short.class) {
			return "INTEGER";
		} else if (type == byte.class || type == Byte.class) {
			return "INTEGER";
		} else if (type == float.class || type == Float.class) {
			return "REAL";
		} else if (type == double.class || type == Double.class) {
			return "REAL";
		} else if (type == char.class || type == Character.class) {
			return "TEXT";
		} else if (type == String.class) {
			return "TEXT";
		} else if (type == boolean.class || type == Boolean.class) {
			return "TEXT";
		} else if (type == Date.class) {
			return "INTEGER";
		} else if (Serializable.class.isAssignableFrom(type)) {
			return "BLOB";
		} else {
			return "TEXT";
		}
	}

	/**
	 * 将T obj 的所有属性转为ContentValues
	 * 
	 * @param obj
	 * @return
	 */
	public static <T> ContentValues getContentValue(T obj) {
		ContentValues values = new ContentValues();
		Class<?> clazz = obj.getClass();
		Field[] fields = clazz.getDeclaredFields();
		if (!CheckUtils.isArrayEmpty(fields)) {
			for (Field field : fields) {
				field.setAccessible(true);
				String name = field.getName();
				Column anno = field.getAnnotation(Column.class);
				if (anno != null) {
					if (anno.primaryKey()) {
						continue;
					}
				}
				Class<?> type = field.getType();
				try {
					if (type == int.class || type == Integer.class) {
						values.put(name, Integer.valueOf(field.getInt(obj)));
					} else if (type == long.class || type == Long.class) {
						values.put(name, Long.valueOf(field.getLong(obj)));
					} else if (type == short.class || type == Short.class) {
						values.put(name, Short.valueOf(field.getShort(obj)));
					} else if (type == float.class || type == Float.class) {
						values.put(name, Float.valueOf(field.getFloat(obj)));
					} else if (type == double.class || type == Double.class) {
						values.put(name, Double.valueOf(field.getDouble(obj)));
					} else if (type == boolean.class || type == Boolean.class) {
						values.put(name, Boolean.valueOf(field.getBoolean(obj)));
					} else if (type == byte.class || type == Byte.class) {
						values.put(name, Byte.valueOf(field.getByte(obj)));
					} else if (type == String.class) {
						values.put(name, (String) field.get(obj));
					}
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				}
			}
		}
		return values;
	}

	/** 获取属性值 */
	public static <T> Object getFiledValue(Class<T> clazz, T obj,
			String fieldName) {
		try {
			Field field = clazz.getDeclaredField(fieldName);
			field.setAccessible(true);
			Class<?> type = field.getType();
			if (type == int.class || type == Integer.class) {
				return Integer.valueOf(field.getInt(obj));
			} else if (type == long.class || type == Long.class) {
				return Long.valueOf(field.getLong(obj));
			} else if (type == short.class || type == Short.class) {
				return Short.valueOf(field.getShort(obj));
			} else if (type == float.class || type == Float.class) {
				return Float.valueOf(field.getFloat(obj));
			} else if (type == double.class || type == Double.class) {
				return Double.valueOf(field.getDouble(obj));
			} else if (type == boolean.class || type == Boolean.class) {
				return Boolean.valueOf(field.getBoolean(obj));
			} else if (type == byte.class || type == Byte.class) {
				return Byte.valueOf(field.getByte(obj));
			} else if (type == String.class) {
				return (String) field.get(obj);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/** 获取主键的值 */
	public static <T> String getPrimaryKeyValue(Class<T> clazz, T obj,
			String fieldName) {
		try {
			Field field = clazz.getDeclaredField(fieldName);
			field.setAccessible(true);
			Class<?> type = field.getType();
			if (type == int.class || type == Integer.class) {
				return String.valueOf(field.getInt(obj));
			} else if (type == long.class || type == Long.class) {
				return String.valueOf(field.getLong(obj));
			} else if (type == short.class || type == Short.class) {
				return String.valueOf(field.getShort(obj));
			} else if (type == float.class || type == Float.class) {
				return String.valueOf(field.getFloat(obj));
			} else if (type == double.class || type == Double.class) {
				return String.valueOf(field.getDouble(obj));
			} else if (type == boolean.class || type == Boolean.class) {
				return String.valueOf(field.getBoolean(obj));
			} else if (type == byte.class || type == Byte.class) {
				return String.valueOf(field.getByte(obj));
			} else if (type == String.class) {
				return (String) field.get(obj);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 设置属性值
	 * 
	 * @throws Exception
	 */
	public static <T> void setFieldValue(Class<T> mClazz, ColumnInfo item,
			T obj, Cursor cursor) throws Exception {
		Field field = mClazz.getField(item.originName);
		int index = cursor.getColumnIndex(item.dbName);
		Class<?> type = item.originType;
		if (type == int.class || type == Integer.class) {
			field.setInt(obj, cursor.getInt(index));
		} else if (type == long.class || type == Long.class) {
			field.setLong(obj, cursor.getLong(index));
		} else if (type == short.class || type == Short.class) {
			field.setShort(obj, cursor.getShort(index));
		} else if (type == float.class || type == Float.class) {
			field.setFloat(obj, cursor.getFloat(index));
		} else if (type == double.class || type == Double.class) {
			field.setDouble(obj, cursor.getDouble(index));
		} else if (type == byte.class || type == Byte.class) {
			field.setByte(obj, (byte) cursor.getInt(index));
		} else if (type == boolean.class || type == Boolean.class) {
			field.setBoolean(obj, Boolean.valueOf(cursor.getString(index)));
		} else if (type == char.class || type == Character.class) {
			field.setChar(obj, cursor.getString(index).charAt(0));
		} else if (type == String.class) {
			field.set(obj, cursor.getString(index));
		}
	}
}
